home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume15 / stevie / part01 next >
Encoding:
Internet Message Format  |  1988-06-05  |  57.8 KB

  1. Subject:  v15i037:  Stevie, an "aspiring" VI clone for Unix, OS/2, Amiga, Part01/04
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: onecom!wldrdg!tony (Tony Andrews)
  7. Posting-number: Volume 15, Issue 37
  8. Archive-name: stevie/part01
  9.  
  10. [  The original distribution referred to a "ctags" clone.  I removed
  11.    it, as ctags is available from your nearest comp.sources.unix archive,
  12.    and I believe  with the GNU distribution.  I repacked the archive.  --r$  ]
  13.  
  14. STEVIE is a vi clone I've been working on for quite a while now. It
  15. began as an Atari ST editor written by Tim Thompson and posted to the
  16. net about a year ago. I've hacked on it off and on since then and ported
  17. it to UNIX and OS/2.
  18.  
  19. This is a reasonably stable release. There's plenty of work to be done
  20. still, but there's been a lot of interest in comp.os.minix recently so
  21. I thought I'd go ahead a post the current version.
  22.  
  23. The system-dependent files for the ST, UNIX, and OS/2 are all included.
  24.  
  25. Thanks...
  26.  
  27. Tony Andrews            UUCP: onecom!wldrdg!tony
  28. Netwise, Inc.            Phone:303-442-8280
  29. 4745 Walnut St.
  30. Boulder, CO 80301
  31.  
  32. #! /bin/sh
  33. # This is a shell archive.  Remove anything before this line, then unpack
  34. # it by saving it into a file and typing "sh file".  To overwrite existing
  35. # files, type "sh file -c".  You can also feed this as standard input via
  36. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  37. # will see the following message at the end:
  38. #        "End of archive 1 (of 4)."
  39. # Contents:  MANIFEST README alloc.c ascii.h fileio.c hexchars.c
  40. #   keymap.h linefunc.c makefile.os2 makefile.tos makefile.usg mark.c
  41. #   os2.c param.c param.h porting.doc ptrfunc.c source.doc term.h
  42. #   tos.c unix.c
  43. # Wrapped by rsalz@fig.bbn.com on Sun Jun  5 11:45:36 1988
  44. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  45. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  46.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  47. else
  48. echo shar: Extracting \"'MANIFEST'\" \(1044 characters\)
  49. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  50. X   File Name        Archive #    Description
  51. X-----------------------------------------------------------
  52. X MANIFEST                   1    This shipping list
  53. X README                     1    
  54. X alloc.c                    1    
  55. X ascii.h                    1    
  56. X cmdline.c                  2    
  57. X edit.c                     2    
  58. X fileio.c                   1    
  59. X help.c                     2    
  60. X hexchars.c                 1    
  61. X keymap.h                   1    
  62. X linefunc.c                 1    
  63. X main.c                     2    
  64. X makefile.os2               1    
  65. X makefile.tos               1    
  66. X makefile.usg               1    
  67. X mark.c                     1    
  68. X misccmds.c                 2    
  69. X normal.c                   4    
  70. X os2.c                      1    
  71. X param.c                    1    
  72. X param.h                    1    
  73. X porting.doc                1    
  74. X ptrfunc.c                  1    
  75. X screen.c                   3    
  76. X search.c                   3    
  77. X source.doc                 1    
  78. X stevie.doc                 3    
  79. X term.h                     1    
  80. X tos.c                      1    
  81. X unix.c                     1    
  82. END_OF_FILE
  83. if test 1044 -ne `wc -c <'MANIFEST'`; then
  84.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  85. fi
  86. # end of 'MANIFEST'
  87. fi
  88. if test -f 'README' -a "${1}" != "-c" ; then 
  89.   echo shar: Will not clobber existing file \"'README'\"
  90. else
  91. echo shar: Extracting \"'README'\" \(1257 characters\)
  92. sed "s/^X//" >'README' <<'END_OF_FILE'
  93. STEVIE Source Release
  94. X
  95. This is a source release of the STEVIE editor, a public domain clone
  96. of the UNIX editor 'vi'. The program was originally developed for the
  97. Atari ST, but has been ported to UNIX and OS/2 as well.
  98. X
  99. To compile STEVIE, you'll also need Henry Spencer's regular expression
  100. library.
  101. X
  102. The files included in this release are:
  103. X
  104. README
  105. X    This file.
  106. X
  107. stevie.doc
  108. X    Reference manual for STEVIE. Assumes familiarity with vi.
  109. X
  110. source.doc
  111. X    Quick overview of the major data structures used.
  112. X
  113. porting.doc
  114. X    Tips for porting STEVIE to other systems.
  115. X
  116. makefile.os2
  117. makefile.usg
  118. makefile.tos
  119. X    Makefiles for OS/2, UNIX System V, and the Atari ST respectively.
  120. X
  121. os2.c
  122. unix.c
  123. tos.c
  124. X    System-dependent routines for the same.
  125. X
  126. alloc.c ascii.h cmdline.c edit.c fileio.c help.c hexchars.c
  127. keymap.h linefunc.c main.c mark.c misccmds.c normal.c param.c
  128. param.h ptrfunc.c screen.c search.c stevie.h term.h
  129. X
  130. X    C source and header files for STEVIE.
  131. X
  132. To compile STEVIE for one of the provided systems:
  133. X
  134. X    1. Compile the regular expression library and install as
  135. X       appropriate for your system.
  136. X
  137. X    2. Edit the file 'stevie.h' to set the system defines as needed.
  138. X
  139. X    3. Check the makefile for your system, and modify as needed.
  140. X
  141. X    4. Compile.
  142. X
  143. Good Luck...
  144. X
  145. Tony Andrews
  146. X3/12/88
  147. END_OF_FILE
  148. if test 1257 -ne `wc -c <'README'`; then
  149.     echo shar: \"'README'\" unpacked with wrong size!
  150. fi
  151. # end of 'README'
  152. fi
  153. if test -f 'alloc.c' -a "${1}" != "-c" ; then 
  154.   echo shar: Will not clobber existing file \"'alloc.c'\"
  155. else
  156. echo shar: Extracting \"'alloc.c'\" \(3967 characters\)
  157. sed "s/^X//" >'alloc.c' <<'END_OF_FILE'
  158. X/*
  159. X * STevie - ST editor for VI enthusiasts.    ...Tim Thompson...twitch!tjt...
  160. X *
  161. X * Extensive modifications by:  Tony Andrews       onecom!wldrdg!tony
  162. X *
  163. X */
  164. X
  165. X#include "stevie.h"
  166. X
  167. X/*
  168. X * This file contains various routines dealing with allocation and
  169. X * deallocation of data structures.
  170. X */
  171. X
  172. char *
  173. alloc(size)
  174. unsigned size;
  175. X{
  176. X    char *p;        /* pointer to new storage space */
  177. X
  178. X    p = malloc(size);
  179. X    if ( p == (char *)NULL ) {    /* if there is no more room... */
  180. X        emsg("alloc() is unable to find memory!");
  181. X    }
  182. X    return(p);
  183. X}
  184. X
  185. char *
  186. strsave(string)
  187. char *string;
  188. X{
  189. X    return(strcpy(alloc((unsigned)(strlen(string)+1)),string));
  190. X}
  191. X
  192. void
  193. screenalloc()
  194. X{
  195. X    /*
  196. X     * If we're changing the size of the screen, free the old arrays
  197. X     */
  198. X    if (Realscreen != NULL)
  199. X        free(Realscreen);
  200. X    if (Nextscreen != NULL)
  201. X        free(Nextscreen);
  202. X
  203. X    Realscreen = malloc((unsigned)(Rows*Columns));
  204. X    Nextscreen = malloc((unsigned)(Rows*Columns));
  205. X}
  206. X
  207. X/*
  208. X * Allocate and initialize a new line structure with room for
  209. X * 'nchars' characters.
  210. X */
  211. LINE *
  212. newline(nchars)
  213. int    nchars;
  214. X{
  215. X    register LINE    *l;
  216. X
  217. X    if ((l = (LINE *) alloc(sizeof(LINE))) == NULL)
  218. X        return (LINE *) NULL;
  219. X
  220. X    l->s = alloc(nchars);        /* the line is empty */
  221. X    l->s[0] = NUL;
  222. X    l->size = nchars;
  223. X
  224. X    l->prev = (LINE *) NULL;    /* should be initialized by caller */
  225. X    l->next = (LINE *) NULL;
  226. X
  227. X    return l;
  228. X}
  229. X
  230. X/*
  231. X * filealloc() - construct an initial empty file buffer
  232. X */
  233. void
  234. filealloc()
  235. X{
  236. X    if ((Filemem->linep = newline(1)) == NULL) {
  237. X        fprintf(stderr,"Unable to allocate file memory!\n");
  238. X        exit(1);
  239. X    }
  240. X    if ((Fileend->linep = newline(1)) == NULL) {
  241. X        fprintf(stderr,"Unable to allocate file memory!\n");
  242. X        exit(1);
  243. X    }
  244. X    Filemem->index = 0;
  245. X    Fileend->index = 0;
  246. X
  247. X    Filemem->linep->next = Fileend->linep;
  248. X    Fileend->linep->prev = Filemem->linep;
  249. X
  250. X    *Curschar = *Filemem;
  251. X    *Topchar  = *Filemem;
  252. X
  253. X    Filemem->linep->num = 0;
  254. X    Fileend->linep->num = 0xffff;
  255. X
  256. X    clrall();        /* clear all marks */
  257. X}
  258. X
  259. X/*
  260. X * freeall() - free the current buffer
  261. X *
  262. X * Free all lines in the current buffer.
  263. X */
  264. void
  265. freeall()
  266. X{
  267. X    LINE    *lp, *xlp;
  268. X
  269. X    for (lp = Filemem->linep; lp != NULL ;lp = xlp) {
  270. X        if (lp->s != NULL)
  271. X            free(lp->s);
  272. X        xlp = lp->next;
  273. X        free(lp);
  274. X    }
  275. X
  276. X    Curschar->linep = NULL;        /* clear pointers */
  277. X    Filemem->linep = NULL;
  278. X    Fileend->linep = NULL;
  279. X}
  280. X
  281. X/*
  282. X * bufempty() - return TRUE if the buffer is empty
  283. X */
  284. bool_t
  285. bufempty()
  286. X{
  287. X    return (buf1line() && Filemem->linep->s[0] == NUL);
  288. X}
  289. X
  290. X/*
  291. X * buf1line() - return TRUE if there is only one line
  292. X */
  293. bool_t
  294. buf1line()
  295. X{
  296. X    return (Filemem->linep->next == Fileend->linep);
  297. X}
  298. X
  299. X/*
  300. X * lineempty() - return TRUE if the current line is empty
  301. X */
  302. bool_t
  303. lineempty()
  304. X{
  305. X    return (Curschar->linep->s[0] == NUL);
  306. X}
  307. X
  308. X/*
  309. X * endofline() - return TRUE if the given position is at end of line
  310. X *
  311. X * This routine will probably never be called with a position resting
  312. X * on the NUL byte, but handle it correctly in case it happens.
  313. X */
  314. bool_t
  315. endofline(p)
  316. register LPTR    *p;
  317. X{
  318. X    return (p->linep->s[p->index] == NUL || p->linep->s[p->index+1] == NUL);
  319. X}
  320. X/*
  321. X * canincrease(n) - returns TRUE if the current line can be increased 'n' bytes
  322. X *
  323. X * This routine returns immediately if the requested space is available.
  324. X * If not, it attempts to allocate the space and adjust the data structures
  325. X * accordingly. If everything fails it returns FALSE.
  326. X */
  327. bool_t
  328. canincrease(n)
  329. register int    n;
  330. X{
  331. X    register int    nsize;
  332. X    register char    *s;        /* pointer to new space */
  333. X
  334. X    nsize = strlen(Curschar->linep->s) + 1 + n;    /* size required */
  335. X
  336. X    if (nsize <= Curschar->linep->size)
  337. X        return TRUE;
  338. X
  339. X    /*
  340. X     * Need to allocate more space for the string. Allow some extra
  341. X     * space on the assumption that we may need it soon. This avoids
  342. X     * excessive numbers of calls to malloc while entering new text.
  343. X     */
  344. X    if ((s = alloc(nsize + SLOP)) == NULL) {
  345. X        emsg("Can't add anything, file is too big!");
  346. X        State = NORMAL;
  347. X        return FALSE;
  348. X    }
  349. X
  350. X    Curschar->linep->size = nsize + SLOP;
  351. X    strcpy(s, Curschar->linep->s);
  352. X    free(Curschar->linep->s);
  353. X    Curschar->linep->s = s;
  354. X    
  355. X    return TRUE;
  356. X}
  357. END_OF_FILE
  358. if test 3967 -ne `wc -c <'alloc.c'`; then
  359.     echo shar: \"'alloc.c'\" unpacked with wrong size!
  360. fi
  361. # end of 'alloc.c'
  362. fi
  363. if test -f 'ascii.h' -a "${1}" != "-c" ; then 
  364.   echo shar: Will not clobber existing file \"'ascii.h'\"
  365. else
  366. echo shar: Extracting \"'ascii.h'\" \(358 characters\)
  367. sed "s/^X//" >'ascii.h' <<'END_OF_FILE'
  368. X/*
  369. X * STEVIE - ST Editor for VI Enthusiasts   ...Tim Thompson...twitch!tjt...
  370. X *
  371. X * Extensive modifications by:  Tony Andrews       onecom!wldrdg!tony
  372. X *
  373. X */
  374. X
  375. X/*
  376. X * Definitions of various common control characters
  377. X */
  378. X
  379. X#define    NUL    '\0'
  380. X#define    BS    '\010'
  381. X#define    TAB    '\011'
  382. X#define    NL    '\012'
  383. X#define    CR    '\015'
  384. X#define    ESC    '\033'
  385. X
  386. X#define    CTRL(x)    ((x) & 0x1f)
  387. END_OF_FILE
  388. if test 358 -ne `wc -c <'ascii.h'`; then
  389.     echo shar: \"'ascii.h'\" unpacked with wrong size!
  390. fi
  391. # end of 'ascii.h'
  392. fi
  393. if test -f 'fileio.c' -a "${1}" != "-c" ; then 
  394.   echo shar: Will not clobber existing file \"'fileio.c'\"
  395. else
  396. echo shar: Extracting \"'fileio.c'\" \(4113 characters\)
  397. sed "s/^X//" >'fileio.c' <<'END_OF_FILE'
  398. X/*
  399. X * STEVIE - ST Editor for VI Enthusiasts   ...Tim Thompson...twitch!tjt...
  400. X *
  401. X * Extensive modifications by:  Tony Andrews       onecom!wldrdg!tony
  402. X *
  403. X */
  404. X
  405. X#include "stevie.h"
  406. X
  407. void
  408. filemess(s)
  409. char *s;
  410. X{
  411. X    smsg("\"%s\" %s", (Filename == NULL) ? "" : Filename, s);
  412. X}
  413. X
  414. void
  415. renum()
  416. X{
  417. X    LPTR    *p;
  418. X    unsigned int l = 0;
  419. X
  420. X    for (p = Filemem; p != NULL ;p = nextline(p), l += LINEINC)
  421. X        p->linep->num = l;
  422. X
  423. X    Fileend->linep->num = 0xffff;
  424. X}
  425. X
  426. X#ifdef    MEGAMAX
  427. overlay "fileio"
  428. X#endif
  429. X
  430. bool_t
  431. readfile(fname,fromp,nochangename)
  432. char    *fname;
  433. LPTR    *fromp;
  434. bool_t    nochangename;    /* if TRUE, don't change the Filename */
  435. X{
  436. X    FILE    *f, *fopen();
  437. X    LINE    *curr;
  438. X    char    buff[1024];
  439. X    char    *p;
  440. X    int    i, c;
  441. X    long    nchars;
  442. X    int    unprint = 0;
  443. X    int    linecnt = 0;
  444. X    bool_t    wasempty = bufempty();
  445. X
  446. X    curr = fromp->linep;
  447. X
  448. X    if ( ! nochangename )
  449. X        Filename = strsave(fname);
  450. X
  451. X    if ( (f=fopen(fname,"r")) == NULL )
  452. X        return TRUE;
  453. X
  454. X    filemess("");
  455. X
  456. X    for (i=nchars=0; (c=getc(f)) != EOF ;nchars++) {
  457. X        if (c >= 0x80) {
  458. X            c -= 0x80;
  459. X            unprint++;
  460. X        }
  461. X
  462. X        /*
  463. X         * Nulls are special, so they can't show up in the file.
  464. X         * We should count nulls seperate from other nasties, but
  465. X         * this is okay for now.
  466. X         */
  467. X        if (c == NUL) {
  468. X            unprint++;
  469. X            continue;
  470. X        }
  471. X
  472. X        if (c == '\n') {    /* process the completed line */
  473. X            int    len;
  474. X            LINE    *lp;
  475. X
  476. X            buff[i] = '\0';
  477. X            len = strlen(buff) + 1;
  478. X            if ((lp = newline(len)) == NULL)
  479. X                exit(1);
  480. X
  481. X            strcpy(lp->s, buff);
  482. X
  483. X            curr->next->prev = lp;    /* new line to next one */
  484. X            lp->next = curr->next;
  485. X
  486. X            curr->next = lp;    /* new line to prior one */
  487. X            lp->prev = curr;
  488. X
  489. X            curr = lp;        /* new line becomes current */
  490. X            i = 0;
  491. X            linecnt++;
  492. X        }
  493. X        else
  494. X            buff[i++] = c;
  495. X    }
  496. X    fclose(f);
  497. X
  498. X    /*
  499. X     * If the buffer was empty when we started, we have to go back
  500. X     * and remove the "dummy" line at Filemem and patch up the ptrs.
  501. X     */
  502. X    if (wasempty) {
  503. X        LINE    *dummy = Filemem->linep;    /* dummy line ptr */
  504. X
  505. X        free(dummy->s);                /* free string space */
  506. X        Filemem->linep = Filemem->linep->next;
  507. X        free(dummy);                /* free LINE struct */
  508. X        Filemem->linep->prev = NULL;
  509. X
  510. X        Curschar->linep = Filemem->linep;
  511. X        Topchar->linep  = Filemem->linep;
  512. X    }
  513. X
  514. X    if ( unprint > 0 )
  515. X        p="\"%s\" %d lines, %ld characters (%d un-printable))";
  516. X    else
  517. X        p="\"%s\" %d lines, %ld characters";
  518. X
  519. X    sprintf(buff, p, fname, linecnt, nchars, unprint);
  520. X    msg(buff);
  521. X    renum();
  522. X    return FALSE;
  523. X}
  524. X
  525. X
  526. X/*
  527. X * writeit - write to file 'fname' lines 'start' through 'end'
  528. X *
  529. X * If either 'start' or 'end' contain null line pointers, the default
  530. X * is to use the start or end of the file respectively.
  531. X */
  532. bool_t
  533. writeit(fname, start, end)
  534. char    *fname;
  535. LPTR    *start, *end;
  536. X{
  537. X    FILE    *f, *fopen();
  538. X    FILE    *fopenb();        /* open in binary mode, where needed */
  539. X    char    buff[80];
  540. X    char    backup[16], *s;
  541. X    long    nchars;
  542. X    int    lines;
  543. X    LPTR    *p;
  544. X
  545. X    sprintf(buff, "\"%s\"", fname);
  546. X    msg(buff);
  547. X
  548. X    /*
  549. X     * Form the backup file name - change foo.* to foo.bak
  550. X     */
  551. X    strcpy(backup, fname);
  552. X    for (s = backup; *s && *s != '.' ;s++)
  553. X        ;
  554. X    *s = NUL;
  555. X    strcat(backup, ".bak");
  556. X
  557. X    /*
  558. X     * Delete any existing backup and move the current version
  559. X     * to the backup. For safety, we don't remove the backup
  560. X     * until the write has finished successfully. And if the
  561. X     * 'backup' option is set, leave it around.
  562. X     */
  563. X    rename(fname, backup);
  564. X
  565. X
  566. X    f = P(P_CR) ? fopen(fname, "w") : fopenb(fname, "w");
  567. X
  568. X    if ( f == NULL ) {
  569. X        emsg("Can't open file for writing!");
  570. X        return FALSE;
  571. X    }
  572. X
  573. X    /*
  574. X     * If we were given a bound, start there. Otherwise just
  575. X     * start at the beginning of the file.
  576. X     */
  577. X    if (start == NULL || start->linep == NULL)
  578. X        p = Filemem;
  579. X    else
  580. X        p = start;
  581. X
  582. X    lines = nchars = 0;
  583. X    do {
  584. X        fprintf(f, "%s\n", p->linep->s);
  585. X        nchars += strlen(p->linep->s) + 1;
  586. X        lines++;
  587. X
  588. X        /*
  589. X         * If we were given an upper bound, and we just did that
  590. X         * line, then bag it now.
  591. X         */
  592. X        if (end != NULL && end->linep != NULL) {
  593. X            if (end->linep == p->linep)
  594. X                break;
  595. X        }
  596. X
  597. X    } while ((p = nextline(p)) != NULL);
  598. X
  599. X    fclose(f);
  600. X    sprintf(buff,"\"%s\" %d lines, %ld characters", fname, lines, nchars);
  601. X    msg(buff);
  602. X    UNCHANGED;
  603. X
  604. X    /*
  605. X     * Remove the backup unless they want it left around
  606. X     */
  607. X    if (!P(P_BK))
  608. X        remove(backup);
  609. X
  610. X    return TRUE;
  611. X}
  612. END_OF_FILE
  613. if test 4113 -ne `wc -c <'fileio.c'`; then
  614.     echo shar: \"'fileio.c'\" unpacked with wrong size!
  615. fi
  616. # end of 'fileio.c'
  617. fi
  618. if test -f 'hexchars.c' -a "${1}" != "-c" ; then 
  619.   echo shar: Will not clobber existing file \"'hexchars.c'\"
  620. else
  621. echo shar: Extracting \"'hexchars.c'\" \(3075 characters\)
  622. sed "s/^X//" >'hexchars.c' <<'END_OF_FILE'
  623. X/*
  624. X * STevie - ST editor for VI enthusiasts.    ...Tim Thompson...twitch!tjt...
  625. X *
  626. X * Extensive modifications by:  Tony Andrews       onecom!wldrdg!tony
  627. X *
  628. X */
  629. X
  630. X#include "stevie.h"
  631. X
  632. X/*
  633. X * This file shows how to display characters on the screen. This is
  634. X * approach is something of an overkill. It's a remnant from the
  635. X * original code that isn't worth messing with for now. TABS are
  636. X * special-cased depending on the value of the "list" parameter.
  637. X */
  638. X
  639. struct charinfo chars[] = {
  640. X    /* 000 */    1, NULL,
  641. X    /* 001 */    2, "^A",
  642. X    /* 002 */    2, "^B",
  643. X    /* 003 */    2, "^C",
  644. X    /* 004 */    2, "^D",
  645. X    /* 005 */    2, "^E",
  646. X    /* 006 */    2, "^F",
  647. X    /* 007 */    2, "^G",
  648. X    /* 010 */    2, "^H",
  649. X    /* 011 */    2, "^I",
  650. X    /* 012 */    7, "[ERROR]",    /* shouldn't occur */
  651. X    /* 013 */    2, "^K",
  652. X    /* 014 */    2, "^L",
  653. X    /* 015 */    2, "^M",
  654. X    /* 016 */    2, "^N",
  655. X    /* 017 */    2, "^O",
  656. X    /* 020 */    2, "^P",
  657. X    /* 021 */    2, "^Q",
  658. X    /* 022 */    2, "^R",
  659. X    /* 023 */    2, "^S",
  660. X    /* 024 */    2, "^T",
  661. X    /* 025 */    2, "^U",
  662. X    /* 026 */    2, "^V",
  663. X    /* 027 */    2, "^W",
  664. X    /* 030 */    2, "^X",
  665. X    /* 031 */    2, "^Y",
  666. X    /* 032 */    2, "^Z",
  667. X    /* 033 */    2, "^[",
  668. X    /* 034 */    2, "^\\",
  669. X    /* 035 */    2, "^]",
  670. X    /* 036 */    2, "^^",
  671. X    /* 037 */    2, "^_",
  672. X    /* 040 */    1, NULL,
  673. X    /* 041 */    1, NULL,
  674. X    /* 042 */    1, NULL,
  675. X    /* 043 */    1, NULL,
  676. X    /* 044 */    1, NULL,
  677. X    /* 045 */    1, NULL,
  678. X    /* 046 */    1, NULL,
  679. X    /* 047 */    1, NULL,
  680. X    /* 050 */    1, NULL,
  681. X    /* 051 */    1, NULL,
  682. X    /* 052 */    1, NULL,
  683. X    /* 053 */    1, NULL,
  684. X    /* 054 */    1, NULL,
  685. X    /* 055 */    1, NULL,
  686. X    /* 056 */    1, NULL,
  687. X    /* 057 */    1, NULL,
  688. X    /* 060 */    1, NULL,
  689. X    /* 061 */    1, NULL,
  690. X    /* 062 */    1, NULL,
  691. X    /* 063 */    1, NULL,
  692. X    /* 064 */    1, NULL,
  693. X    /* 065 */    1, NULL,
  694. X    /* 066 */    1, NULL,
  695. X    /* 067 */    1, NULL,
  696. X    /* 070 */    1, NULL,
  697. X    /* 071 */    1, NULL,
  698. X    /* 072 */    1, NULL,
  699. X    /* 073 */    1, NULL,
  700. X    /* 074 */    1, NULL,
  701. X    /* 075 */    1, NULL,
  702. X    /* 076 */    1, NULL,
  703. X    /* 077 */    1, NULL,
  704. X    /* 100 */    1, NULL,
  705. X    /* 101 */    1, NULL,
  706. X    /* 102 */    1, NULL,
  707. X    /* 103 */    1, NULL,
  708. X    /* 104 */    1, NULL,
  709. X    /* 105 */    1, NULL,
  710. X    /* 106 */    1, NULL,
  711. X    /* 107 */    1, NULL,
  712. X    /* 110 */    1, NULL,
  713. X    /* 111 */    1, NULL,
  714. X    /* 112 */    1, NULL,
  715. X    /* 113 */    1, NULL,
  716. X    /* 114 */    1, NULL,
  717. X    /* 115 */    1, NULL,
  718. X    /* 116 */    1, NULL,
  719. X    /* 117 */    1, NULL,
  720. X    /* 120 */    1, NULL,
  721. X    /* 121 */    1, NULL,
  722. X    /* 122 */    1, NULL,
  723. X    /* 123 */    1, NULL,
  724. X    /* 124 */    1, NULL,
  725. X    /* 125 */    1, NULL,
  726. X    /* 126 */    1, NULL,
  727. X    /* 127 */    1, NULL,
  728. X    /* 130 */    1, NULL,
  729. X    /* 131 */    1, NULL,
  730. X    /* 132 */    1, NULL,
  731. X    /* 133 */    1, NULL,
  732. X    /* 134 */    1, NULL,
  733. X    /* 135 */    1, NULL,
  734. X    /* 136 */    1, NULL,
  735. X    /* 137 */    1, NULL,
  736. X    /* 140 */    1, NULL,
  737. X    /* 141 */    1, NULL,
  738. X    /* 142 */    1, NULL,
  739. X    /* 143 */    1, NULL,
  740. X    /* 144 */    1, NULL,
  741. X    /* 145 */    1, NULL,
  742. X    /* 146 */    1, NULL,
  743. X    /* 147 */    1, NULL,
  744. X    /* 150 */    1, NULL,
  745. X    /* 151 */    1, NULL,
  746. X    /* 152 */    1, NULL,
  747. X    /* 153 */    1, NULL,
  748. X    /* 154 */    1, NULL,
  749. X    /* 155 */    1, NULL,
  750. X    /* 156 */    1, NULL,
  751. X    /* 157 */    1, NULL,
  752. X    /* 160 */    1, NULL,
  753. X    /* 161 */    1, NULL,
  754. X    /* 162 */    1, NULL,
  755. X    /* 163 */    1, NULL,
  756. X    /* 164 */    1, NULL,
  757. X    /* 165 */    1, NULL,
  758. X    /* 166 */    1, NULL,
  759. X    /* 167 */    1, NULL,
  760. X    /* 170 */    1, NULL,
  761. X    /* 171 */    1, NULL,
  762. X    /* 172 */    1, NULL,
  763. X    /* 173 */    1, NULL,
  764. X    /* 174 */    1, NULL,
  765. X    /* 175 */    1, NULL,
  766. X    /* 176 */    1, NULL,
  767. X    /* 177 */    5, "[DEL]",
  768. X};
  769. END_OF_FILE
  770. if test 3075 -ne `wc -c <'hexchars.c'`; then
  771.     echo shar: \"'hexchars.c'\" unpacked with wrong size!
  772. fi
  773. # end of 'hexchars.c'
  774. fi
  775. if test -f 'keymap.h' -a "${1}" != "-c" ; then 
  776.   echo shar: Will not clobber existing file \"'keymap.h'\"
  777. else
  778. echo shar: Extracting \"'keymap.h'\" \(1008 characters\)
  779. sed "s/^X//" >'keymap.h' <<'END_OF_FILE'
  780. X/*
  781. X * STEVIE - ST Editor for VI Enthusiasts   ...Tim Thompson...twitch!tjt...
  782. X *
  783. X * Extensive modifications by:  Tony Andrews       onecom!wldrdg!tony
  784. X *
  785. X */
  786. X
  787. X/*
  788. X * Keycode definitions for special keys
  789. X *
  790. X * On systems that have any of these keys, the routine 'inchar' in the
  791. X * machine-dependent code should return one of the codes here.
  792. X */
  793. X
  794. X#define    K_HELP        0x80
  795. X#define    K_UNDO        0x81
  796. X#define    K_INSERT    0x82
  797. X#define    K_HOME        0x83
  798. X#define    K_UARROW    0x84
  799. X#define    K_DARROW    0x85
  800. X#define    K_LARROW    0x86
  801. X#define    K_RARROW    0x87
  802. X#define    K_CGRAVE    0x88    /* control grave accent */
  803. X
  804. X#define    K_F1        0x91    /* function keys */
  805. X#define    K_F2        0x92
  806. X#define    K_F3        0x93
  807. X#define    K_F4        0x94
  808. X#define    K_F5        0x95
  809. X#define    K_F6        0x96
  810. X#define    K_F7        0x97
  811. X#define    K_F8        0x98
  812. X#define    K_F9        0x99
  813. X#define    K_F10        0x9a
  814. X
  815. X#define    K_SF1        0xa1    /* shifted function keys */
  816. X#define    K_SF2        0xa2
  817. X#define    K_SF3        0xa3
  818. X#define    K_SF4        0xa4
  819. X#define    K_SF5        0xa5
  820. X#define    K_SF6        0xa6
  821. X#define    K_SF7        0xa7
  822. X#define    K_SF8        0xa8
  823. X#define    K_SF9        0xa9
  824. X#define    K_SF10        0xaa
  825. END_OF_FILE
  826. if test 1008 -ne `wc -c <'keymap.h'`; then
  827.     echo shar: \"'keymap.h'\" unpacked with wrong size!
  828. fi
  829. # end of 'keymap.h'
  830. fi
  831. if test -f 'linefunc.c' -a "${1}" != "-c" ; then 
  832.   echo shar: Will not clobber existing file \"'linefunc.c'\"
  833. else
  834. echo shar: Extracting \"'linefunc.c'\" \(1590 characters\)
  835. sed "s/^X//" >'linefunc.c' <<'END_OF_FILE'
  836. X/*
  837. X * STevie - ST editor for VI enthusiasts.    ...Tim Thompson...twitch!tjt...
  838. X *
  839. X * Extensive modifications by:  Tony Andrews       onecom!wldrdg!tony
  840. X *
  841. X */
  842. X
  843. X#include "stevie.h"
  844. X
  845. X/*
  846. X * nextline(curr)
  847. X *
  848. X * Return a pointer to the beginning of the next line after the one
  849. X * referenced by 'curr'. Return NULL if there is no next line (at EOF).
  850. X */
  851. X
  852. LPTR *
  853. nextline(curr)
  854. LPTR *curr;
  855. X{
  856. X    static    LPTR    next;
  857. X
  858. X    if (curr->linep->next != Fileend->linep) {
  859. X        next.index = 0;
  860. X        next.linep = curr->linep->next;
  861. X        return &next;
  862. X    }
  863. X    return (LPTR *) NULL;
  864. X}
  865. X
  866. X/*
  867. X * prevline(curr)
  868. X *
  869. X * Return a pointer to the beginning of the line before the one
  870. X * referenced by 'curr'. Return NULL if there is no prior line.
  871. X */
  872. X
  873. LPTR *
  874. prevline(curr)
  875. LPTR *curr;
  876. X{
  877. X    static    LPTR    prev;
  878. X
  879. X    if (curr->linep->prev != NULL) {
  880. X        prev.index = 0;
  881. X        prev.linep = curr->linep->prev;
  882. X        return &prev;
  883. X    }
  884. X    return (LPTR *) NULL;
  885. X}
  886. X
  887. X/*
  888. X * coladvance(p,col)
  889. X *
  890. X * Try to advance to the specified column, starting at p.
  891. X */
  892. X
  893. LPTR *
  894. coladvance(p, col)
  895. LPTR    *p;
  896. int    col;
  897. X{
  898. X    static    LPTR    lp;
  899. X    int    c, in;
  900. X
  901. X    lp.linep = p->linep;
  902. X    lp.index = p->index;
  903. X
  904. X    /* If we're on a blank ('\n' only) line, we can't do anything */
  905. X    if (lp.linep->s[lp.index] == '\0')
  906. X        return &lp;
  907. X    /* try to advance to the specified column */
  908. X    for ( c=0; col-- > 0; c++ ) {
  909. X        /* Count a tab for what it's worth (if list mode not on) */
  910. X        if ( gchar(&lp) == TAB && !P(P_LS) ) {
  911. X            in = ((P(P_TS)-1) - c%P(P_TS));
  912. X            col -= in;
  913. X            c += in;
  914. X        }
  915. X        /* Don't go past the end of */
  916. X        /* the file or the line. */
  917. X        if (inc(&lp)) {
  918. X            dec(&lp);
  919. X            break;
  920. X        }
  921. X    }
  922. X    return &lp;
  923. X}
  924. END_OF_FILE
  925. if test 1590 -ne `wc -c <'linefunc.c'`; then
  926.     echo shar: \"'linefunc.c'\" unpacked with wrong size!
  927. fi
  928. # end of 'linefunc.c'
  929. fi
  930. if test -f 'makefile.os2' -a "${1}" != "-c" ; then 
  931.   echo shar: Will not clobber existing file \"'makefile.os2'\"
  932. else
  933. echo shar: Extracting \"'makefile.os2'\" \(1343 characters\)
  934. sed "s/^X//" >'makefile.os2' <<'END_OF_FILE'
  935. X#
  936. X# Makefile for OS/2
  937. X#
  938. X# The make command with OS/2 is really stupid.
  939. X#
  940. X
  941. LIBS = ..\regexp\regexp.obj ..\regexp\regsub.obj
  942. X
  943. X#
  944. X# Compact model lets us edit large files, but keep small model code
  945. X#
  946. MODEL= -AC
  947. CFLAGS = $(MODEL) -I..\regexp
  948. X
  949. MACH=    os2.obj
  950. X
  951. OBJ=    main.obj edit.obj linefunc.obj normal.obj cmdline.obj hexchars.obj \
  952. X    misccmds.obj help.obj ptrfunc.obj search.obj alloc.obj \
  953. X    mark.obj screen.obj fileio.obj param.obj $(MACH)
  954. X
  955. main.obj:    main.c
  956. X    cl -c $(CFLAGS) main.c
  957. X
  958. alloc.obj : alloc.c
  959. X    cl -c $(CFLAGS) alloc.c
  960. X
  961. edit.obj : edit.c
  962. X    cl -c $(CFLAGS) edit.c
  963. X
  964. linefunc.obj : linefunc.c
  965. X    cl -c $(CFLAGS) linefunc.c
  966. X
  967. normal.obj : normal.c
  968. X    cl -c $(CFLAGS) normal.c
  969. X
  970. cmdline.obj : cmdline.c
  971. X    cl -c $(CFLAGS) cmdline.c
  972. X
  973. hexchars.obj : hexchars.c
  974. X    cl -c $(CFLAGS) hexchars.c
  975. X
  976. misccmds.obj : misccmds.c
  977. X    cl -c $(CFLAGS) misccmds.c
  978. X
  979. help.obj : help.c
  980. X    cl -c $(CFLAGS) help.c
  981. X
  982. ptrfunc.obj : ptrfunc.c
  983. X    cl -c $(CFLAGS) ptrfunc.c
  984. X
  985. search.obj : search.c
  986. X    cl -c $(CFLAGS) search.c
  987. X
  988. mark.obj : mark.c
  989. X    cl -c $(CFLAGS) mark.c
  990. X
  991. screen.obj : screen.c
  992. X    cl -c $(CFLAGS) screen.c
  993. X
  994. fileio.obj : fileio.c
  995. X    cl -c $(CFLAGS) fileio.c
  996. X
  997. param.obj : param.c
  998. X    cl -c $(CFLAGS) param.c
  999. X
  1000. os2.obj : os2.c
  1001. X    cl -c $(CFLAGS) os2.c
  1002. X
  1003. stevie.exe : $(OBJ)
  1004. X    cl $(MODEL) *.obj $(LIBS) -o stevie.exe
  1005. X    copy stevie.exe rstevie.exe
  1006. X    bind rstevie.exe \lib\api.lib \lib\doscalls.lib
  1007. END_OF_FILE
  1008. if test 1343 -ne `wc -c <'makefile.os2'`; then
  1009.     echo shar: \"'makefile.os2'\" unpacked with wrong size!
  1010. fi
  1011. # end of 'makefile.os2'
  1012. fi
  1013. if test -f 'makefile.tos' -a "${1}" != "-c" ; then 
  1014.   echo shar: Will not clobber existing file \"'makefile.tos'\"
  1015. else
  1016. echo shar: Extracting \"'makefile.tos'\" \(815 characters\)
  1017. sed "s/^X//" >'makefile.tos' <<'END_OF_FILE'
  1018. X#
  1019. X# Makefile for the Atari ST - Megamax C compiler
  1020. X#
  1021. X
  1022. LIBS = \megamax\regexp.lib
  1023. X
  1024. CFLAGS = -DMEGAMAX
  1025. X
  1026. X#    Megamax rule
  1027. X.c.o:
  1028. X    mmcc $(CFLAGS) $<
  1029. X    mmimp $*.o
  1030. X    mmlib rv vi.lib $*.o
  1031. X
  1032. MACH=    tos.o
  1033. X
  1034. OBJ=    main.o edit.o linefunc.o normal.o cmdline.o hexchars.o \
  1035. X    misccmds.o help.o ptrfunc.o search.o alloc.o \
  1036. X    mark.o screen.o fileio.o param.o $(MACH)
  1037. X
  1038. all : stevie.ttp
  1039. X
  1040. stevie.ttp : $(OBJ)
  1041. X    $(LINKER) vi.lib $(LIBS) -o stevie.ttp
  1042. X
  1043. clean :
  1044. X    $(RM) $(OBJ) vi.lib
  1045. X
  1046. arc :
  1047. X    arc a vi.arc alloc.c ascii.h cmdline.c edit.c
  1048. X    arc a vi.arc fileio.c help.c hexchars.c keymap.h linefunc.c
  1049. X    arc a vi.arc main.c makefile.os2 makefile.tos makefile.usg mark.c
  1050. X    arc a vi.arc misccmds.c normal.c os2.c param.c param.h porting.doc
  1051. X    arc a vi.arc ptrfunc.c readme screen.c search.c source.doc stevie.doc
  1052. X    arc a vi.arc stevie.h term.h tos.c unix.c
  1053. END_OF_FILE
  1054. if test 815 -ne `wc -c <'makefile.tos'`; then
  1055.     echo shar: \"'makefile.tos'\" unpacked with wrong size!
  1056. fi
  1057. # end of 'makefile.tos'
  1058. fi
  1059. if test -f 'makefile.usg' -a "${1}" != "-c" ; then 
  1060.   echo shar: Will not clobber existing file \"'makefile.usg'\"
  1061. else
  1062. echo shar: Extracting \"'makefile.usg'\" \(346 characters\)
  1063. sed "s/^X//" >'makefile.usg' <<'END_OF_FILE'
  1064. X#
  1065. X# Makefile for UNIX (System V)
  1066. X#
  1067. X
  1068. LIBS = ../regexp/regexp.a
  1069. LDFLAGS=
  1070. X
  1071. CFLAGS = -I../regexp -O
  1072. X
  1073. MACH=    unix.o
  1074. X
  1075. OBJ=    main.o edit.o linefunc.o normal.o cmdline.o hexchars.o \
  1076. X    misccmds.o help.o ptrfunc.o search.o alloc.o \
  1077. X    mark.o screen.o fileio.o param.o $(MACH)
  1078. X
  1079. all : stevie
  1080. X
  1081. stevie : $(OBJ)
  1082. X    $(CC) $(OBJ) $(LIBS) -o stevie
  1083. X
  1084. clean :
  1085. X    rm $(OBJ)
  1086. END_OF_FILE
  1087. if test 346 -ne `wc -c <'makefile.usg'`; then
  1088.     echo shar: \"'makefile.usg'\" unpacked with wrong size!
  1089. fi
  1090. # end of 'makefile.usg'
  1091. fi
  1092. if test -f 'mark.c' -a "${1}" != "-c" ; then 
  1093.   echo shar: Will not clobber existing file \"'mark.c'\"
  1094. else
  1095. echo shar: Extracting \"'mark.c'\" \(2257 characters\)
  1096. sed "s/^X//" >'mark.c' <<'END_OF_FILE'
  1097. X/*
  1098. X * STevie - ST editor for VI enthusiasts.
  1099. X *
  1100. X * Extensive modifications by:  Tony Andrews       onecom!wldrdg!tony
  1101. X *
  1102. X */
  1103. X
  1104. X#include "stevie.h"
  1105. X
  1106. X#ifdef    MEGAMAX
  1107. overlay "mark"
  1108. X#endif
  1109. X
  1110. X/*
  1111. X * This file contains routines to maintain and manipulate marks.
  1112. X */
  1113. X
  1114. X#define    NMARKS    10        /* max. # of marks that can be saved */
  1115. X
  1116. struct    mark {
  1117. X    char    name;
  1118. X    LPTR    pos;
  1119. X};
  1120. X
  1121. static    struct    mark    mlist[NMARKS];
  1122. static    struct    mark    pcmark;        /* previous context mark */
  1123. static    bool_t    pcvalid = FALSE;    /* true if pcmark is valid */
  1124. X
  1125. X/*
  1126. X * setmark(c) - set mark 'c' at current cursor position
  1127. X *
  1128. X * Returns TRUE on success, FALSE if no room for mark or bad name given.
  1129. X */
  1130. bool_t
  1131. setmark(c)
  1132. char    c;
  1133. X{
  1134. X    int    i;
  1135. X
  1136. X    if (!isalpha(c))
  1137. X        return FALSE;
  1138. X
  1139. X    /*
  1140. X     * If there is already a mark of this name, then just use the
  1141. X     * existing mark entry.
  1142. X     */
  1143. X    for (i=0; i < NMARKS ;i++) {
  1144. X        if (mlist[i].name == c) {
  1145. X            mlist[i].pos = *Curschar;
  1146. X            return TRUE;
  1147. X        }
  1148. X    }
  1149. X
  1150. X    /*
  1151. X     * There wasn't a mark of the given name, so find a free slot
  1152. X     */
  1153. X    for (i=0; i < NMARKS ;i++) {
  1154. X        if (mlist[i].name == NUL) {    /* got a free one */
  1155. X            mlist[i].name = c;
  1156. X            mlist[i].pos = *Curschar;
  1157. X            return TRUE;
  1158. X        }
  1159. X    }
  1160. X    return FALSE;
  1161. X}
  1162. X
  1163. X/*
  1164. X * setpcmark() - set the previous context mark to the current position
  1165. X */
  1166. void
  1167. setpcmark()
  1168. X{
  1169. X    pcmark.pos = *Curschar;
  1170. X    pcvalid = TRUE;
  1171. X}
  1172. X
  1173. X/*
  1174. X * getmark(c) - find mark for char 'c'
  1175. X *
  1176. X * Return pointer to LPTR or NULL if no such mark.
  1177. X */
  1178. LPTR *
  1179. getmark(c)
  1180. char    c;
  1181. X{
  1182. X    register int    i;
  1183. X
  1184. X    if (c == '\'' || c == '`')    /* previous context mark */
  1185. X        return pcvalid ? &(pcmark.pos) : (LPTR *) NULL;
  1186. X
  1187. X    for (i=0; i < NMARKS ;i++) {
  1188. X        if (mlist[i].name == c)
  1189. X            return &(mlist[i].pos);
  1190. X    }
  1191. X    return (LPTR *) NULL;
  1192. X}
  1193. X
  1194. X/*
  1195. X * clrall() - clear all marks
  1196. X *
  1197. X * Used mainly when trashing the entire buffer during ":e" type commands
  1198. X */
  1199. void
  1200. clrall()
  1201. X{
  1202. X    register int    i;
  1203. X
  1204. X    for (i=0; i < NMARKS ;i++)
  1205. X        mlist[i].name = NUL;
  1206. X    pcvalid = FALSE;
  1207. X}
  1208. X
  1209. X/*
  1210. X * clrmark(line) - clear any marks for 'line'
  1211. X *
  1212. X * Used any time a line is deleted so we don't have marks pointing to
  1213. X * non-existent lines.
  1214. X */
  1215. void
  1216. clrmark(line)
  1217. LINE    *line;
  1218. X{
  1219. X    register int    i;
  1220. X
  1221. X    for (i=0; i < NMARKS ;i++) {
  1222. X        if (mlist[i].pos.linep == line)
  1223. X            mlist[i].name = NUL;
  1224. X    }
  1225. X    if (pcvalid && (pcmark.pos.linep == line))
  1226. X        pcvalid = FALSE;
  1227. X}
  1228. END_OF_FILE
  1229. if test 2257 -ne `wc -c <'mark.c'`; then
  1230.     echo shar: \"'mark.c'\" unpacked with wrong size!
  1231. fi
  1232. # end of 'mark.c'
  1233. fi
  1234. if test -f 'os2.c' -a "${1}" != "-c" ; then 
  1235.   echo shar: Will not clobber existing file \"'os2.c'\"
  1236. else
  1237. echo shar: Extracting \"'os2.c'\" \(1581 characters\)
  1238. sed "s/^X//" >'os2.c' <<'END_OF_FILE'
  1239. X/*
  1240. X * OS/2 System-dependent routines.
  1241. X */
  1242. X
  1243. X#include "stevie.h"
  1244. X
  1245. X/*
  1246. X * inchar() - get a character from the keyboard
  1247. X */
  1248. int
  1249. inchar()
  1250. X{
  1251. X    int    c;
  1252. X
  1253. X    flushbuf();        /* flush any pending output */
  1254. X
  1255. X    c = getch();
  1256. X
  1257. X    if (c == 0x1e)        /* control-^ */
  1258. X        return K_CGRAVE;
  1259. X    else
  1260. X        return c;
  1261. X}
  1262. X
  1263. X#define    BSIZE    2048
  1264. static    char    outbuf[BSIZE];
  1265. static    int    bpos = 0;
  1266. X
  1267. flushbuf()
  1268. X{
  1269. X    if (bpos != 0)
  1270. X        write(1, outbuf, bpos);
  1271. X    bpos = 0;
  1272. X}
  1273. X
  1274. X/*
  1275. X * Macro to output a character. Used within this file for speed.
  1276. X */
  1277. X#define    outone(c)    outbuf[bpos++] = c; if (bpos >= BSIZE) flushbuf()
  1278. X
  1279. X/*
  1280. X * Function version for use outside this file.
  1281. X */
  1282. void
  1283. outchar(c)
  1284. register char    c;
  1285. X{
  1286. X    outbuf[bpos++] = c;
  1287. X    if (bpos >= BSIZE)
  1288. X        flushbuf();
  1289. X}
  1290. X
  1291. void
  1292. outstr(s)
  1293. register char    *s;
  1294. X{
  1295. X    while (*s) {
  1296. X        outone(*s++);
  1297. X    }
  1298. X}
  1299. X
  1300. void
  1301. beep()
  1302. X{
  1303. X    outone('\007');
  1304. X}
  1305. X
  1306. sleep(n)
  1307. int    n;
  1308. X{
  1309. X    extern    far pascal DOSSLEEP();
  1310. X
  1311. X    DOSSLEEP(1000L * n);
  1312. X}
  1313. X
  1314. void
  1315. delay()
  1316. X{
  1317. X    DOSSLEEP(500L);
  1318. X}
  1319. X
  1320. void
  1321. windinit()
  1322. X{
  1323. X    Columns = 80;
  1324. X    P(P_LI) = Rows = 25;
  1325. X}
  1326. X
  1327. void
  1328. windexit(r)
  1329. int r;
  1330. X{
  1331. X    flushbuf();
  1332. X    exit(r);
  1333. X}
  1334. X
  1335. void
  1336. windgoto(r, c)
  1337. register int    r, c;
  1338. X{
  1339. X    r += 1;
  1340. X    c += 1;
  1341. X
  1342. X    /*
  1343. X     * Check for overflow once, to save time.
  1344. X     */
  1345. X    if (bpos + 8 >= BSIZE)
  1346. X        flushbuf();
  1347. X
  1348. X    outbuf[bpos++] = '\033';
  1349. X    outbuf[bpos++] = '[';
  1350. X    if (r >= 10)
  1351. X        outbuf[bpos++] = r/10 + '0';
  1352. X    outbuf[bpos++] = r%10 + '0';
  1353. X    outbuf[bpos++] = ';';
  1354. X    if (c >= 10)
  1355. X        outbuf[bpos++] = c/10 + '0';
  1356. X    outbuf[bpos++] = c%10 + '0';
  1357. X    outbuf[bpos++] = 'H';
  1358. X}
  1359. X
  1360. XFILE *
  1361. fopenb(fname, mode)
  1362. char    *fname;
  1363. char    *mode;
  1364. X{
  1365. X    FILE    *fopen();
  1366. X    char    modestr[16];
  1367. X
  1368. X    sprintf(modestr, "%sb", mode);
  1369. X    return fopen(fname, modestr);
  1370. X}
  1371. END_OF_FILE
  1372. if test 1581 -ne `wc -c <'os2.c'`; then
  1373.     echo shar: \"'os2.c'\" unpacked with wrong size!
  1374. fi
  1375. # end of 'os2.c'
  1376. fi
  1377. if test -f 'param.c' -a "${1}" != "-c" ; then 
  1378.   echo shar: Will not clobber existing file \"'param.c'\"
  1379. else
  1380. echo shar: Extracting \"'param.c'\" \(3830 characters\)
  1381. sed "s/^X//" >'param.c' <<'END_OF_FILE'
  1382. X/*
  1383. X * STEVIE - ST Editor for VI Enthusiasts   ...Tim Thompson...twitch!tjt...
  1384. X *
  1385. X * Extensive modifications by:  Tony Andrews       onecom!wldrdg!tony
  1386. X *
  1387. X */
  1388. X
  1389. X/*
  1390. X * Code to handle user-settable parameters. This is all pretty much table-
  1391. X * driven. To add a new parameter, put it in the params array, and add a
  1392. X * macro for it in param.h. If it's a numeric parameter, add any necessary
  1393. X * bounds checks to doset(). String parameters aren't currently supported.
  1394. X */
  1395. X
  1396. X#include "stevie.h"
  1397. X
  1398. struct    param    params[] = {
  1399. X
  1400. X    { "tabstop",    "ts",        8,    P_NUM },
  1401. X    { "scroll",    "scroll",    12,    P_NUM },
  1402. X    { "report",    "report",    5,    P_NUM },
  1403. X    { "lines",    "lines",    25,    P_NUM },
  1404. X
  1405. X    { "vbell",    "vb",        TRUE,    P_BOOL },
  1406. X    { "showmatch",    "sm",        FALSE,    P_BOOL },
  1407. X    { "wrapscan",    "ws",        TRUE,    P_BOOL },
  1408. X    { "errorbells",    "eb",        FALSE,    P_BOOL },
  1409. X    { "showmode",    "mo",        FALSE,    P_BOOL },
  1410. X    { "backup",    "bk",        FALSE,    P_BOOL },
  1411. X    { "return",    "cr",        TRUE,    P_BOOL },
  1412. X    { "list",    "list",        FALSE,    P_BOOL },
  1413. X#if 0
  1414. X    /* not yet implemented */
  1415. X    { "autoindent",    "ai",        FALSE,    P_BOOL },
  1416. X#endif
  1417. X    { "",        "",        0,    0, }        /* end marker */
  1418. X
  1419. X};
  1420. X
  1421. static    void    showparms();
  1422. X
  1423. void
  1424. doset(arg, inter)
  1425. char    *arg;        /* parameter string */
  1426. bool_t    inter;        /* TRUE if called interactively */
  1427. X{
  1428. X    int    i;
  1429. X    char    *s;
  1430. X    bool_t    did_lines = FALSE;
  1431. X
  1432. X    bool_t    state = TRUE;        /* new state of boolean parms. */
  1433. X
  1434. X    if (arg == NULL) {
  1435. X        showparms(FALSE);
  1436. X        return;
  1437. X    }
  1438. X    if (strncmp(arg, "all", 3) == 0) {
  1439. X        showparms(TRUE);
  1440. X        return;
  1441. X    }
  1442. X    if (strncmp(arg, "no", 2) == 0) {
  1443. X        state = FALSE;
  1444. X        arg += 2;
  1445. X    }
  1446. X
  1447. X    for (i=0; params[i].fullname[0] != NUL ;i++) {
  1448. X        s = params[i].fullname;
  1449. X        if (strncmp(arg, s, strlen(s)) == 0)    /* matched full name */
  1450. X            break;
  1451. X        s = params[i].shortname;
  1452. X        if (strncmp(arg, s, strlen(s)) == 0)    /* matched short name */
  1453. X            break;
  1454. X    }
  1455. X
  1456. X    if (params[i].fullname[0] != NUL) {    /* found a match */
  1457. X        if (params[i].flags & P_NUM) {
  1458. X            did_lines = (i == P_LI);
  1459. X            if (inter && (arg[strlen(s)] != '=' || state == FALSE))
  1460. X                emsg("Invalid set of numeric parameter");
  1461. X            else {
  1462. X                params[i].value = atoi(arg+strlen(s)+1);
  1463. X                params[i].flags |= P_CHANGED;
  1464. X            }
  1465. X        } else /* boolean */ {
  1466. X            if (inter && (arg[strlen(s)] == '='))
  1467. X                emsg("Invalid set of boolean parameter");
  1468. X            else {
  1469. X                params[i].value = state;
  1470. X                params[i].flags |= P_CHANGED;
  1471. X            }
  1472. X        }
  1473. X    } else {
  1474. X        if (inter)
  1475. X            emsg("Unrecognized 'set' option");
  1476. X    }
  1477. X
  1478. X    /*
  1479. X     * Update the screen in case we changed something like "tabstop"
  1480. X     * or "list" that will change its appearance.
  1481. X     */
  1482. X    if (inter)
  1483. X        updatescreen();
  1484. X
  1485. X    if (did_lines) {
  1486. X        Rows = P(P_LI);
  1487. X        screenalloc();        /* allocate new screen buffers */
  1488. X        screenclear();
  1489. X        updatescreen();
  1490. X    }
  1491. X    /*
  1492. X     * Check the bounds for numeric parameters here
  1493. X     */
  1494. X    if (P(P_TS) <= 0 || P(P_TS) > 32) {
  1495. X        if (inter)
  1496. X            emsg("Invalid tab size specified");
  1497. X        P(P_TS) = 8;
  1498. X        return;
  1499. X    }
  1500. X
  1501. X    if (P(P_SS) <= 0 || P(P_SS) > Rows) {
  1502. X        if (inter)
  1503. X            emsg("Invalid scroll size specified");
  1504. X        P(P_SS) = 12;
  1505. X        return;
  1506. X    }
  1507. X
  1508. X    /*
  1509. X     * Check for another argument, and call doset() recursively, if
  1510. X     * found. If any argument results in an error, no further
  1511. X     * parameters are processed.
  1512. X     */
  1513. X    while (*arg != ' ' && *arg != '\t') {    /* skip to next white space */
  1514. X        if (*arg == NUL)
  1515. X            return;            /* end of parameter list */
  1516. X        arg++;
  1517. X    }
  1518. X    while (*arg == ' ' || *arg == '\t')    /* skip to next non-white */
  1519. X        arg++;
  1520. X
  1521. X    if (*arg)
  1522. X        doset(arg);    /* recurse on next parameter, if present */
  1523. X}
  1524. X
  1525. static    void
  1526. showparms(all)
  1527. bool_t    all;    /* show ALL parameters */
  1528. X{
  1529. X    struct    param    *p;
  1530. X    char    buf[64];
  1531. X
  1532. X    gotocmd(TRUE, TRUE, 0);
  1533. X    outstr("Parameters:\r\n");
  1534. X
  1535. X    for (p = ¶ms[0]; p->fullname[0] != NUL ;p++) {
  1536. X        if (!all && ((p->flags & P_CHANGED) == 0))
  1537. X            continue;
  1538. X        if (p->flags & P_BOOL)
  1539. X            sprintf(buf, "\t%s%s\r\n",
  1540. X                (p->value ? "" : "no"), p->fullname);
  1541. X        else
  1542. X            sprintf(buf, "\t%s=%d\r\n", p->fullname, p->value);
  1543. X
  1544. X        outstr(buf);
  1545. X    }
  1546. X    wait_return();
  1547. X}
  1548. END_OF_FILE
  1549. if test 3830 -ne `wc -c <'param.c'`; then
  1550.     echo shar: \"'param.c'\" unpacked with wrong size!
  1551. fi
  1552. # end of 'param.c'
  1553. fi
  1554. if test -f 'param.h' -a "${1}" != "-c" ; then 
  1555.   echo shar: Will not clobber existing file \"'param.h'\"
  1556. else
  1557. echo shar: Extracting \"'param.h'\" \(1311 characters\)
  1558. sed "s/^X//" >'param.h' <<'END_OF_FILE'
  1559. X/*
  1560. X * STEVIE - ST Editor for VI Enthusiasts   ...Tim Thompson...twitch!tjt...
  1561. X *
  1562. X * Extensive modifications by:  Tony Andrews       onecom!wldrdg!tony
  1563. X *
  1564. X */
  1565. X
  1566. X/*
  1567. X * Settable parameters
  1568. X */
  1569. X
  1570. struct    param {
  1571. X    char    *fullname;    /* full parameter name */
  1572. X    char    *shortname;    /* permissible abbreviation */
  1573. X    int    value;        /* parameter value */
  1574. X    int    flags;
  1575. X};
  1576. X
  1577. extern    struct    param    params[];
  1578. X
  1579. X/*
  1580. X * Flags
  1581. X */
  1582. X#define    P_BOOL        0x01    /* the parameter is boolean */
  1583. X#define    P_NUM        0x02    /* the parameter is numeric */
  1584. X#define    P_CHANGED    0x04    /* the parameter has been changed */
  1585. X
  1586. X/*
  1587. X * The following are the indices in the params array for each parameter
  1588. X */
  1589. X
  1590. X/*
  1591. X * Numeric parameters
  1592. X */
  1593. X#define    P_TS        0    /* tab size */
  1594. X#define    P_SS        1    /* scroll size */
  1595. X#define    P_RP        2    /* report */
  1596. X#define    P_LI        3    /* lines */
  1597. X
  1598. X/*
  1599. X * Boolean parameters
  1600. X */
  1601. X#define    P_VB        4    /* visual bell */
  1602. X#define    P_SM        5    /* showmatch */
  1603. X#define    P_WS        6    /* wrap scan */
  1604. X#define    P_EB        7    /* error bells */
  1605. X#define    P_MO        8    /* show mode */
  1606. X#define    P_BK        9    /* make backups when writing out files */
  1607. X#define    P_CR        10    /* use cr-lf to terminate lines on writes */
  1608. X#define    P_LS        11    /* show tabs and newlines graphically */
  1609. X
  1610. X#if 0
  1611. X#define    P_AI        12    /* auto-indent (not really in yet) */
  1612. X#endif
  1613. X
  1614. X/*
  1615. X * Macro to get the value of a parameter
  1616. X */
  1617. X#define    P(n)    (params[n].value)
  1618. END_OF_FILE
  1619. if test 1311 -ne `wc -c <'param.h'`; then
  1620.     echo shar: \"'param.h'\" unpacked with wrong size!
  1621. fi
  1622. # end of 'param.h'
  1623. fi
  1624. if test -f 'porting.doc' -a "${1}" != "-c" ; then 
  1625.   echo shar: Will not clobber existing file \"'porting.doc'\"
  1626. else
  1627. echo shar: Extracting \"'porting.doc'\" \(2404 characters\)
  1628. sed "s/^X//" >'porting.doc' <<'END_OF_FILE'
  1629. X
  1630. X         Release Notes for STEVIE - Version 3.10
  1631. X
  1632. X           Atari ST Editor for VI Enthusiasts
  1633. X
  1634. X                    Porting
  1635. X
  1636. X
  1637. X                  Tony Andrews
  1638. X
  1639. X                  3/6/88
  1640. X
  1641. X
  1642. X    Porting the editor is a relatively simple task. Most of the
  1643. code is pretty machine-independent. For each environment, there is
  1644. a file of routines that perform various low-level operations that
  1645. tend to vary a lot from one machine to another. Another file contains
  1646. the escape sequences to be used for each machine.
  1647. X
  1648. X    The machine-dependent files currently used are:
  1649. X
  1650. tos.c:    Atari ST - ifdef for either Megamax or Alcyon
  1651. X
  1652. unix.c:    UNIX System V
  1653. X
  1654. os2.c:    Microsoft OS/2
  1655. X
  1656. X
  1657. X    Each of these files are around 150 lines long and deal with
  1658. low-level issues like character I/O to the terminal, terminal
  1659. initialization, cursor addressing, and so on. There are different
  1660. tradeoffs to be made depending on the environment. For example, the
  1661. UNIX version buffers terminal output because of the relatively high
  1662. overhead of system calls. A quick look at the files will make it clear
  1663. what needs to be done in a new environment.
  1664. X
  1665. X    Terminal escape sequences are in the file "term.h". These are
  1666. defined statically, for the time being. There is some discussion in
  1667. term.h regarding which sequences are optional and which are not. The
  1668. editor is somewhat flexible in dealing with a lack of terminal
  1669. capabilities.
  1670. X
  1671. X    Because not all C compilers support command line macro definitions,
  1672. the #define's for system-specific macros are placed at the beginning of the
  1673. file 'stevie.h'. If you port to a new system, add another line there to
  1674. define the macro you choose for your port.
  1675. X
  1676. X    The basic process for doing a new port is:
  1677. X
  1678. X    1. Come up with a macro name to use when ifdef'ing your system-
  1679. X       specific changes. Add a line at the top of 'stevie.h' to define
  1680. X       the macro name you've chosen.
  1681. X
  1682. X    2. Look at unix.c, tos.c, and os2.c and copy the one that comes
  1683. X       closest to working on your system. Then modify your new file
  1684. X       as needed.
  1685. X
  1686. X    3. Look at term.h and edit the file appropriately adding a new
  1687. X       set of escape sequence definitions for your system.
  1688. X
  1689. X    4. If you haven't already, get a copy of Henry Spencer's regular
  1690. X       expression library and compile it. This has been very simple
  1691. X       every time I've done it.
  1692. X
  1693. X    5. Compiling and debug the editor.
  1694. X
  1695. X
  1696. X    In most cases it should really be that simple. I've done two
  1697. ports (UNIX and OS/2) and both were complete in just a couple of hours.
  1698. END_OF_FILE
  1699. if test 2404 -ne `wc -c <'porting.doc'`; then
  1700.     echo shar: \"'porting.doc'\" unpacked with wrong size!
  1701. fi
  1702. # end of 'porting.doc'
  1703. fi
  1704. if test -f 'ptrfunc.c' -a "${1}" != "-c" ; then 
  1705.   echo shar: Will not clobber existing file \"'ptrfunc.c'\"
  1706. else
  1707. echo shar: Extracting \"'ptrfunc.c'\" \(2571 characters\)
  1708. sed "s/^X//" >'ptrfunc.c' <<'END_OF_FILE'
  1709. X/*
  1710. X * STevie - ST editor for VI enthusiasts.    ...Tim Thompson...twitch!tjt...
  1711. X *
  1712. X * Extensive modifications by:  Tony Andrews       onecom!wldrdg!tony
  1713. X *
  1714. X */
  1715. X
  1716. X#include "stevie.h"
  1717. X
  1718. X/*
  1719. X * The routines in this file attempt to imitate many of the operations
  1720. X * that used to be performed on simple character pointers and are now
  1721. X * performed on LPTR's. This makes it easier to modify other sections
  1722. X * of the code. Think of an LPTR as representing a position in the file.
  1723. X * Positions can be incremented, decremented, compared, etc. through
  1724. X * the functions implemented here.
  1725. X */
  1726. X
  1727. X/*
  1728. X * inc(p)
  1729. X *
  1730. X * Increment the line pointer 'p' crossing line boundaries as necessary.
  1731. X * Return 1 when crossing a line, -1 when at end of file, 0 otherwise.
  1732. X */
  1733. int
  1734. inc(lp)
  1735. register LPTR    *lp;
  1736. X{
  1737. X    register char *p = &(lp->linep->s[lp->index]);
  1738. X
  1739. X    if (*p != NUL) {            /* still within line */
  1740. X        lp->index++;
  1741. X        return ((p[1] != NUL) ? 0 : 1);
  1742. X    }
  1743. X
  1744. X    if (lp->linep->next != Fileend->linep) {  /* there is a next line */
  1745. X        lp->index = 0;
  1746. X        lp->linep = lp->linep->next;
  1747. X        return 1;
  1748. X    }
  1749. X
  1750. X    return -1;
  1751. X}
  1752. X
  1753. X/*
  1754. X * dec(p)
  1755. X *
  1756. X * Decrement the line pointer 'p' crossing line boundaries as necessary.
  1757. X * Return 1 when crossing a line, -1 when at start of file, 0 otherwise.
  1758. X */
  1759. int
  1760. dec(lp)
  1761. register LPTR    *lp;
  1762. X{
  1763. X    if (lp->index > 0) {            /* still within line */
  1764. X        lp->index--;
  1765. X        return 0;
  1766. X    }
  1767. X
  1768. X    if (lp->linep->prev != NULL) {        /* there is a prior line */
  1769. X        lp->linep = lp->linep->prev;
  1770. X        lp->index = strlen(lp->linep->s);
  1771. X        return 1;
  1772. X    }
  1773. X
  1774. X    return -1;                /* at start of file */
  1775. X}
  1776. X
  1777. X/*
  1778. X * gchar(lp) - get the character at position "lp"
  1779. X */
  1780. int
  1781. gchar(lp)
  1782. register LPTR    *lp;
  1783. X{
  1784. X    return (lp->linep->s[lp->index]);
  1785. X}
  1786. X
  1787. X/*
  1788. X * pchar(lp, c) - put character 'c' at position 'lp'
  1789. X */
  1790. void
  1791. pchar(lp, c)
  1792. register LPTR    *lp;
  1793. char    c;
  1794. X{
  1795. X    lp->linep->s[lp->index] = c;
  1796. X}
  1797. X
  1798. X/*
  1799. X * pswap(a, b) - swap two position pointers
  1800. X */
  1801. void
  1802. pswap(a, b)
  1803. register LPTR    *a, *b;
  1804. X{
  1805. X    LPTR    tmp;
  1806. X
  1807. X    tmp = *a;
  1808. X    *a  = *b;
  1809. X    *b  = tmp;
  1810. X}
  1811. X
  1812. X/*
  1813. X * Position comparisons
  1814. X */
  1815. X
  1816. bool_t
  1817. lt(a, b)
  1818. register LPTR    *a, *b;
  1819. X{
  1820. X    register int an, bn;
  1821. X
  1822. X    an = LINEOF(a);
  1823. X    bn = LINEOF(b);
  1824. X
  1825. X    if (an != bn)
  1826. X        return (an < bn);
  1827. X    else
  1828. X        return (a->index < b->index);
  1829. X}
  1830. X
  1831. bool_t
  1832. gt(a, b)
  1833. LPTR    *a, *b;
  1834. X{
  1835. X    register int an, bn;
  1836. X
  1837. X    an = LINEOF(a);
  1838. X    bn = LINEOF(b);
  1839. X
  1840. X    if (an != bn)
  1841. X        return (an > bn);
  1842. X    else
  1843. X        return (a->index > b->index);
  1844. X}
  1845. X
  1846. bool_t
  1847. equal(a, b)
  1848. register LPTR    *a, *b;
  1849. X{
  1850. X    return (a->linep == b->linep && a->index == b->index);
  1851. X}
  1852. X
  1853. bool_t
  1854. ltoreq(a, b)
  1855. register LPTR    *a, *b;
  1856. X{
  1857. X    return (lt(a, b) || equal(a, b));
  1858. X}
  1859. X
  1860. bool_t
  1861. gtoreq(a, b)
  1862. LPTR    *a, *b;
  1863. X{
  1864. X    return (gt(a, b) || equal(a, b));
  1865. X}
  1866. END_OF_FILE
  1867. if test 2571 -ne `wc -c <'ptrfunc.c'`; then
  1868.     echo shar: \"'ptrfunc.c'\" unpacked with wrong size!
  1869. fi
  1870. # end of 'ptrfunc.c'
  1871. fi
  1872. if test -f 'source.doc' -a "${1}" != "-c" ; then 
  1873.   echo shar: Will not clobber existing file \"'source.doc'\"
  1874. else
  1875. echo shar: Extracting \"'source.doc'\" \(4625 characters\)
  1876. sed "s/^X//" >'source.doc' <<'END_OF_FILE'
  1877. X
  1878. X         Release Notes for STEVIE - Version 3.10
  1879. X
  1880. X                  Source Notes
  1881. X
  1882. X                  Tony Andrews
  1883. X
  1884. X                  3/6/88
  1885. X
  1886. X
  1887. Overview
  1888. X--------
  1889. X
  1890. X    This file provides a brief description of the source code for
  1891. Stevie. The data structures are described later as well. For information
  1892. specific to porting the editor, see the file 'porting.doc'. This document
  1893. is more relevant to people who want to hack on the editor apart from doing
  1894. a simple port.
  1895. X
  1896. X    Most of this document was written some time ago so a lot of the
  1897. discussion centers on problems related to the Atari ST environment and
  1898. compilers. Most of this can be ignored for other systems.
  1899. X
  1900. Things You Need
  1901. X---------------
  1902. X
  1903. X    Stevie has been compiled with both the Alcyon (4.14A) and the
  1904. Megamax C compilers. For the posted binary, Megamax was used because
  1905. it's less buggy and provides a reasonable malloc(). Ports to other
  1906. compilers should be pretty simple. The current ifdef's for ALCYON and
  1907. MEGAMAX should point to the potential trouble areas. (See 'porting.doc'
  1908. for more information.)
  1909. X
  1910. X    The search code depends on Henry Spencer's regular expression
  1911. code. I used a version I got from the net recently (as part of a 'grep'
  1912. posting) and had absolutely no trouble compiling it on the ST. Thanks,
  1913. Henry!
  1914. X
  1915. X    The file 'getenv.c' contains a getenv routine that may or may
  1916. not be needed with your compiler. My version works with Alcyon and
  1917. Megamax, under either the Beckemeyer or Gulam shells.
  1918. X
  1919. X    Lastly, you need a decent malloc. Lots of stuff in stevie is
  1920. allocated dynamically. The malloc with Alcyon is problematic because
  1921. it allocates from the heap between the end of data and the top of stack.
  1922. If you make the stack big enough to edit large files, you wind up
  1923. wasting space when working with small files. Mallocs that get their memory
  1924. from GEMDOS (in fairly large chunks) are much better.
  1925. X
  1926. X
  1927. Cruft
  1928. X-----
  1929. X
  1930. X    Some artifacts from Tim Thompson's original version remain. In
  1931. some cases, code has been re-written, with the original left in place
  1932. but ifdef'd out. This will all be cleaned up eventually, but for now
  1933. it's sometimes useful to see how things used to work.
  1934. X
  1935. X
  1936. Data Structures
  1937. X---------------
  1938. X
  1939. X    A brief discussion of the evolution of the data structures will
  1940. do much to clarify the code, and explain some of the strangeness you may
  1941. see.
  1942. X
  1943. X    In the original version, the file was maintained in memory as a
  1944. simple contiguous buffer. References to positions in the file were simply
  1945. character pointers. Due to the obvious performance problems inherent in
  1946. this approach, I made the following changes.
  1947. X
  1948. X    The file is now represented by a doubly linked list of 'line'
  1949. structures defined as follows:
  1950. X
  1951. struct    line {
  1952. X    struct    line    *prev, *next;    /* previous and next lines */
  1953. X    char    *s;            /* text for this line */
  1954. X    int    size;            /* actual size of space at 's' */
  1955. X    unsigned int    num;        /* line "number" */
  1956. X};
  1957. X
  1958. The members of the line structure are described more completely here:
  1959. X
  1960. prev    - pointer to the structure for the prior line, or NULL for the
  1961. X      first line of the file
  1962. X
  1963. next    - like 'prev' but points to the next line
  1964. X
  1965. s    - points to the contents of the line (null terminated)
  1966. X
  1967. size    - contains the size of the chunk of space pointed to by s. This
  1968. X      is used so we know when we can add text to a line without getting
  1969. X      more space. When we DO need more space, we always get a little
  1970. X      extra so we don't make so many calls to malloc.
  1971. X
  1972. num    - This is a pseudo line number that makes it easy to compare
  1973. X      positions within the file. Otherwise, we'd have to traverse
  1974. X      all the links to tell which line came first.
  1975. X
  1976. X
  1977. X    Since character pointers served to mark file positions in the
  1978. original, a similar data object was needed for the new data structures.
  1979. This purpose is served by the 'lptr' structure which is defined as:
  1980. X
  1981. struct    lptr {
  1982. X    struct    line    *linep;        /* line we're referencing */
  1983. X    int    index;            /* position within that line */
  1984. X};
  1985. X
  1986. X
  1987. The member 'linep' points to the 'line' structure for the line containing
  1988. the location of interest. The integer 'index' is the offset into the line
  1989. data (member 's') of the character to be referenced.
  1990. X
  1991. The following typedef's are more commonly used:
  1992. X
  1993. typedef    struct line    LINE;
  1994. typedef    struct lptr    LPTR;
  1995. X
  1996. Many operations that were trivial with character pointers had to be
  1997. implemented by functions to manipulate LPTR's. Most of these are in the
  1998. file 'ptrfunc.c'. There you'll find functions to increment, decrement,
  1999. and compare LPTR's.
  2000. X
  2001. This was the biggest change to the editor. Fortunately, I made this
  2002. change very early on, while I was still doing the work on a UNIX system.
  2003. Using 'sdb' made it much easier to debug this code than if I had done it
  2004. on the ST.
  2005. X
  2006. X
  2007. Summary
  2008. X-------
  2009. X
  2010. END_OF_FILE
  2011. if test 4625 -ne `wc -c <'source.doc'`; then
  2012.     echo shar: \"'source.doc'\" unpacked with wrong size!
  2013. fi
  2014. # end of 'source.doc'
  2015. fi
  2016. if test -f 'term.h' -a "${1}" != "-c" ; then 
  2017.   echo shar: Will not clobber existing file \"'term.h'\"
  2018. else
  2019. echo shar: Extracting \"'term.h'\" \(2817 characters\)
  2020. sed "s/^X//" >'term.h' <<'END_OF_FILE'
  2021. X/*
  2022. X * STEVIE - ST Editor for VI Enthusiasts   ...Tim Thompson...twitch!tjt...
  2023. X *
  2024. X * Extensive modifications by:  Tony Andrews       onecom!wldrdg!tony
  2025. X *
  2026. X */
  2027. X
  2028. X/*
  2029. X * This file contains the machine dependent escape sequences that
  2030. X * the editor needs to perform various operations. Some of the sequences
  2031. X * here are optional. Anything not available should be indicated by
  2032. X * a null string. In the case of insert/delete line sequences, the
  2033. X * editor checks the capability and works around the deficiency, if
  2034. X * necessary.
  2035. X *
  2036. X * Currently, insert/delete line sequences are used for screen scrolling.
  2037. X * There are lots of terminals that have 'index' and 'reverse index'
  2038. X * capabilities, but no line insert/delete. For this reason, the editor
  2039. X * routines s_ins() and s_del() should be modified to use 'index'
  2040. X * sequences when the line to be inserted or deleted line zero.
  2041. X */
  2042. X
  2043. X/*
  2044. X * The macro names here correspond (more or less) to the actual ANSI names
  2045. X */
  2046. X
  2047. X#ifdef    ATARI
  2048. X#define    T_EL    "\033l"        /* erase the entire current line */
  2049. X#define    T_IL    "\033L"        /* insert one line */
  2050. X#define    T_DL    "\033M"        /* delete one line */
  2051. X#define    T_SC    "\033j"        /* save the cursor position */
  2052. X#define    T_ED    "\033E"        /* erase display (may optionally home cursor) */
  2053. X#define    T_RC    "\033k"        /* restore the cursor position */
  2054. X#define    T_CI    "\033f"        /* invisible cursor (very optional) */
  2055. X#define    T_CV    "\033e"        /* visible cursor (very optional) */
  2056. X#endif
  2057. X
  2058. X#ifdef    UNIX
  2059. X/*
  2060. X * The UNIX sequences are hard-wired for ansi-like terminals. I should
  2061. X * really use termcap/terminfo, but the UNIX port was done for profiling,
  2062. X * not for actual use, so it wasn't worth the effort.
  2063. X */
  2064. X#define    T_EL    "\033[2K"    /* erase the entire current line */
  2065. X#define    T_IL    "\033[L"    /* insert one line */
  2066. X#define    T_DL    "\033[M"    /* delete one line */
  2067. X#define    T_ED    "\033[2J"    /* erase display (may optionally home cursor) */
  2068. X#define    T_SC    "\0337"        /* save the cursor position */
  2069. X#define    T_RC    "\0338"        /* restore the cursor position */
  2070. X#define    T_CI    ""        /* invisible cursor (very optional) */
  2071. X#define    T_CV    ""        /* visible cursor (very optional) */
  2072. X#endif
  2073. X
  2074. X#ifdef    OS2
  2075. X/*
  2076. X * The OS/2 ansi console driver is pretty deficient. No insert or delete line
  2077. X * sequences. The erase line sequence only erases from the cursor to the end
  2078. X * of the line. For our purposes that works out okay, since the only time
  2079. X * T_EL is used is when the cursor is in column 0.
  2080. X */
  2081. X#define    T_EL    "\033[K"    /* erase the entire current line */
  2082. X#define    T_IL    ""        /* insert one line */
  2083. X#define    T_DL    ""        /* delete one line */
  2084. X#define    T_ED    "\033[2J"    /* erase display (may optionally home cursor) */
  2085. X#define    T_SC    "\033[s"    /* save the cursor position */
  2086. X#define    T_RC    "\033[u"    /* restore the cursor position */
  2087. X#define    T_CI    ""        /* invisible cursor (very optional) */
  2088. X#define    T_CV    ""        /* visible cursor (very optional) */
  2089. X#endif
  2090. END_OF_FILE
  2091. if test 2817 -ne `wc -c <'term.h'`; then
  2092.     echo shar: \"'term.h'\" unpacked with wrong size!
  2093. fi
  2094. # end of 'term.h'
  2095. fi
  2096. if test -f 'tos.c' -a "${1}" != "-c" ; then 
  2097.   echo shar: Will not clobber existing file \"'tos.c'\"
  2098. else
  2099. echo shar: Extracting \"'tos.c'\" \(5140 characters\)
  2100. sed "s/^X//" >'tos.c' <<'END_OF_FILE'
  2101. X/*
  2102. X * System-dependent routines for the Atari ST.
  2103. X */
  2104. X
  2105. X#include "stevie.h"
  2106. X
  2107. X#include <osbind.h>
  2108. X
  2109. X/*
  2110. X * The following buffer is used to work around a bug in TOS. It appears that
  2111. X * unread console input can cause a crash, but only if console output is
  2112. X * going on. The solution is to always grab any unread input before putting
  2113. X * out a character. The following buffer holds any characters read in this
  2114. X * fashion. The problem can be easily produced because STEVIE can't yet keep
  2115. X * up with the normal auto-repeat rate in insert mode.
  2116. X */
  2117. X#define    IBUFSZ    128
  2118. X
  2119. static long inbuf[IBUFSZ];    /* buffer for unread input */
  2120. static long *inptr = inbuf;    /* where to put next character */
  2121. X
  2122. X/*
  2123. X * inchar() - get a character from the keyboard
  2124. X *
  2125. X * Certain special keys are mapped to values above 0x80. These
  2126. X * mappings are defined in keymap.h. If the key has a non-zero
  2127. X * ascii value, it is simply returned. Otherwise it may be a
  2128. X * special key we want to map.
  2129. X *
  2130. X * The ST has a bug involving keyboard input that seems to occur
  2131. X * when typing quickly, especially typing capital letters. Sometimes
  2132. X * a value of 0x02540000 is read. This doesn't correspond to anything
  2133. X * on the keyboard, according to my documentation. My solution is to
  2134. X * loop when any unknown key is seen. Normally, the bell is rung to
  2135. X * indicate the error. If the "bug" value is seen, we ignore it completely.
  2136. X */
  2137. int
  2138. inchar()
  2139. X{
  2140. X    for (;;) {
  2141. X        long c, *p;
  2142. X
  2143. X        /*
  2144. X         * Get the next input character, either from the input
  2145. X         * buffer or directly from TOS.
  2146. X         */
  2147. X        if (inptr != inbuf) {    /* input in the buffer, use it */
  2148. X            c = inbuf[0];
  2149. X            /*
  2150. X             * Shift everything else in the buffer down. This
  2151. X             * would be cleaner if we used a circular buffer,
  2152. X             * but it really isn't worth it.
  2153. X             */
  2154. X            inptr--;
  2155. X            for (p = inbuf; p < inptr ;p++)
  2156. X                *p = *(p+1);
  2157. X        } else
  2158. X            c = Crawcin();
  2159. X    
  2160. X        if ((c & 0xff) != 0)
  2161. X            return ((int) c);
  2162. X    
  2163. X        switch ((int) (c >> 16) & 0xff) {
  2164. X    
  2165. X        case 0x62: return K_HELP;
  2166. X        case 0x61: return K_UNDO;
  2167. X        case 0x52: return K_INSERT;
  2168. X        case 0x47: return K_HOME;
  2169. X        case 0x48: return K_UARROW;
  2170. X        case 0x50: return K_DARROW;
  2171. X        case 0x4b: return K_LARROW;
  2172. X        case 0x4d: return K_RARROW;
  2173. X        case 0x29: return K_CGRAVE;    /* control grave accent */
  2174. X        
  2175. X        /*
  2176. X         * Occurs due to a bug in TOS.
  2177. X         */
  2178. X        case 0x54:
  2179. X            break;
  2180. X        /*
  2181. X         * Add the function keys here later if we put in support
  2182. X         * for macros.
  2183. X         */
  2184. X    
  2185. X        default:
  2186. X            beep();
  2187. X            break;
  2188. X    
  2189. X        }
  2190. X    }
  2191. X}
  2192. X
  2193. X/*
  2194. X * get_inchars - snarf away any pending console input
  2195. X *
  2196. X * If the buffer overflows, we discard what's left and ring the bell.
  2197. X */
  2198. static void
  2199. get_inchars()
  2200. X{
  2201. X    while (Cconis()) {
  2202. X        if (inptr >= &inbuf[IBUFSZ]) {    /* no room in buffer? */
  2203. X            Crawcin();        /* discard the input */
  2204. X            beep();            /* and sound the alarm */
  2205. X        } else
  2206. X            *inptr++ = Crawcin();
  2207. X    }
  2208. X}
  2209. X
  2210. void
  2211. outchar(c)
  2212. char    c;
  2213. X{
  2214. X    get_inchars();
  2215. X    Cconout(c);
  2216. X}
  2217. X
  2218. void
  2219. outstr(s)
  2220. register char    *s;
  2221. X{
  2222. X    get_inchars();
  2223. X    Cconws(s);
  2224. X}
  2225. X
  2226. X#define    BGND    0
  2227. X#define    TEXT    3
  2228. X
  2229. X/*
  2230. X * vbeep() - visual bell
  2231. X */
  2232. static void
  2233. vbeep()
  2234. X{
  2235. X    int    text, bgnd;        /* text and background colors */
  2236. X    long    l;
  2237. X
  2238. X    text = Setcolor(TEXT, -1);
  2239. X    bgnd = Setcolor(BGND, -1);
  2240. X
  2241. X    Setcolor(TEXT, bgnd);        /* swap colors */
  2242. X    Setcolor(BGND, text);
  2243. X
  2244. X    for (l=0; l < 5000 ;l++)    /* short pause */
  2245. X        ;
  2246. X
  2247. X    Setcolor(TEXT, text);        /* restore colors */
  2248. X    Setcolor(BGND, bgnd);
  2249. X}
  2250. X
  2251. void
  2252. beep()
  2253. X{
  2254. X    if (P(P_VB))
  2255. X        vbeep();
  2256. X    else
  2257. X        outchar('\007');
  2258. X}
  2259. X
  2260. X/*
  2261. X * remove(file) - remove a file
  2262. X */
  2263. void
  2264. remove(file)
  2265. char *file;
  2266. X{
  2267. X    Fdelete(file);
  2268. X}
  2269. X
  2270. X/*
  2271. X * rename(of, nf) - rename existing file 'of' to 'nf'
  2272. X */
  2273. void
  2274. rename(of, nf)
  2275. char    *of, *nf;
  2276. X{
  2277. X    Fdelete(nf);        /* if 'nf' exists, remove it */
  2278. X    Frename(0, of, nf);
  2279. X}
  2280. X
  2281. void
  2282. windinit()
  2283. X{
  2284. X    if (Getrez() == 0)
  2285. X        Columns = 40;        /* low resolution */
  2286. X    else
  2287. X        Columns = 80;        /* medium or high */
  2288. X
  2289. X    P(P_LI) = Rows = 25;
  2290. X
  2291. X    Cursconf(1,NULL);
  2292. X}
  2293. X
  2294. void
  2295. windexit(r)
  2296. int r;
  2297. X{
  2298. X    exit(r);
  2299. X}
  2300. X
  2301. void
  2302. windgoto(r, c)
  2303. int    r, c;
  2304. X{
  2305. X    outstr("\033Y");
  2306. X    outchar(r + 040);
  2307. X    outchar(c + 040);
  2308. X}
  2309. X
  2310. X/*
  2311. X * System calls or library routines missing in TOS.
  2312. X */
  2313. X
  2314. void
  2315. sleep(n)
  2316. int n;
  2317. X{
  2318. X    int k;
  2319. X
  2320. X    k = Tgettime();
  2321. X    while ( Tgettime() <= k+n )
  2322. X        ;
  2323. X}
  2324. X
  2325. void
  2326. delay()
  2327. X{
  2328. X    long    n;
  2329. X
  2330. X    for (n = 0; n < 8000 ;n++)
  2331. X        ;
  2332. X}
  2333. X
  2334. int
  2335. system(cmd)
  2336. char    *cmd;
  2337. X{
  2338. X    char    arg[1];
  2339. X
  2340. X    arg[0] = (char) 0;    /* no arguments passed to the shell */
  2341. X
  2342. X    if (Pexec(0, cmd, arg, 0L) < 0)
  2343. X        return -1;
  2344. X    else
  2345. X        return 0;
  2346. X}
  2347. X
  2348. X#ifdef    MEGAMAX
  2349. char *
  2350. strchr(s, c)
  2351. char    *s;
  2352. int    c;
  2353. X{
  2354. X    do {
  2355. X        if ( *s == c )
  2356. X            return(s);
  2357. X    } while (*s++);
  2358. X    return(NULL);
  2359. X}
  2360. X#endif
  2361. X
  2362. X#ifdef    MEGAMAX
  2363. X
  2364. XFILE *
  2365. fopenb(fname, mode)
  2366. char    *fname;
  2367. char    *mode;
  2368. X{
  2369. X    char    modestr[10];
  2370. X
  2371. X    sprintf(modestr, "b%s", mode);
  2372. X
  2373. X    return fopen(fname, modestr);
  2374. X}
  2375. X
  2376. X#endif
  2377. X
  2378. X/*
  2379. X * getenv() - get a string from the environment
  2380. X *
  2381. X * Both Alcyon and Megamax are missing getenv(). This routine works for
  2382. X * both compilers and with the Beckemeyer and Gulam shells. With gulam,
  2383. X * the env_style variable should be set to either "mw" or "gu".
  2384. X */
  2385. char *
  2386. getenv(name)
  2387. char *name;
  2388. X{
  2389. X    extern long _base;
  2390. X    char *envp, *p;
  2391. X
  2392. X    envp = *((char **) (_base + 0x2c));
  2393. X
  2394. X    for (; *envp ;envp += strlen(envp)+1) {
  2395. X        if (strncmp(envp, name, strlen(name)) == 0) {
  2396. X            p = envp + strlen(name);
  2397. X            if (*p++ == '=')
  2398. X                return p;
  2399. X        }
  2400. X    }
  2401. X    return (char *) 0;
  2402. X}
  2403. END_OF_FILE
  2404. if test 5140 -ne `wc -c <'tos.c'`; then
  2405.     echo shar: \"'tos.c'\" unpacked with wrong size!
  2406. fi
  2407. # end of 'tos.c'
  2408. fi
  2409. if test -f 'unix.c' -a "${1}" != "-c" ; then 
  2410.   echo shar: Will not clobber existing file \"'unix.c'\"
  2411. else
  2412. echo shar: Extracting \"'unix.c'\" \(2241 characters\)
  2413. sed "s/^X//" >'unix.c' <<'END_OF_FILE'
  2414. X/*
  2415. X * System-dependent routines for UNIX System V Release 3.
  2416. X */
  2417. X
  2418. X#include "stevie.h"
  2419. X#include <termio.h>
  2420. X
  2421. X/*
  2422. X * inchar() - get a character from the keyboard
  2423. X */
  2424. int
  2425. inchar()
  2426. X{
  2427. X    char    c;
  2428. X
  2429. X    flushbuf();        /* flush any pending output */
  2430. X
  2431. X    while (read(0, &c, 1) != 1)
  2432. X        ;
  2433. X
  2434. X    return c;
  2435. X}
  2436. X
  2437. X#define    BSIZE    2048
  2438. static    char    outbuf[BSIZE];
  2439. static    int    bpos = 0;
  2440. X
  2441. flushbuf()
  2442. X{
  2443. X    if (bpos != 0)
  2444. X        write(1, outbuf, bpos);
  2445. X    bpos = 0;
  2446. X}
  2447. X
  2448. X/*
  2449. X * Macro to output a character. Used within this file for speed.
  2450. X */
  2451. X#define    outone(c)    outbuf[bpos++] = c; if (bpos >= BSIZE) flushbuf()
  2452. X
  2453. X/*
  2454. X * Function version for use outside this file.
  2455. X */
  2456. void
  2457. outchar(c)
  2458. register char    c;
  2459. X{
  2460. X    outbuf[bpos++] = c;
  2461. X    if (bpos >= BSIZE)
  2462. X        flushbuf();
  2463. X}
  2464. X
  2465. void
  2466. outstr(s)
  2467. register char    *s;
  2468. X{
  2469. X    while (*s) {
  2470. X        outone(*s++);
  2471. X    }
  2472. X}
  2473. X
  2474. void
  2475. beep()
  2476. X{
  2477. X    outone('\007');
  2478. X}
  2479. X
  2480. X/*
  2481. X * remove(file) - remove a file
  2482. X */
  2483. void
  2484. remove(file)
  2485. char *file;
  2486. X{
  2487. X    unlink(file);
  2488. X}
  2489. X
  2490. X/*
  2491. X * rename(of, nf) - rename existing file 'of' to 'nf'
  2492. X */
  2493. void
  2494. rename(of, nf)
  2495. char    *of, *nf;
  2496. X{
  2497. X    unlink(nf);
  2498. X    link(of, nf);
  2499. X    unlink(of);
  2500. X}
  2501. X
  2502. void
  2503. delay()
  2504. X{
  2505. X    /* not implemented */
  2506. X}
  2507. X
  2508. static    struct    termio    ostate;
  2509. X
  2510. void
  2511. windinit()
  2512. X{
  2513. X    char    *getenv();
  2514. X    char    *term;
  2515. X    struct    termio    nstate;
  2516. X
  2517. X    if ((term = getenv("TERM")) == NULL || strcmp(term, "vt100") != 0) {
  2518. X        fprintf(stderr, "Invalid terminal type '%s'\n", term);
  2519. X        exit(1);
  2520. X    }
  2521. X    Columns = 80;
  2522. X    P(P_LI) = Rows = 24;
  2523. X
  2524. X    /*
  2525. X     * Go into cbreak mode
  2526. X     */
  2527. X     ioctl(0, TCGETA, &ostate);
  2528. X     nstate = ostate;
  2529. X     nstate.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);
  2530. X     nstate.c_cc[VMIN] = 1;
  2531. X     nstate.c_cc[VTIME] = 0;
  2532. X     ioctl(0, TCSETAW, &nstate);
  2533. X}
  2534. X
  2535. void
  2536. windexit(r)
  2537. int r;
  2538. X{
  2539. X    /*
  2540. X     * Restore terminal modes
  2541. X     */
  2542. X    ioctl(0, TCSETAW, &ostate);
  2543. X
  2544. X    exit(r);
  2545. X}
  2546. X
  2547. X#define    outone(c)    outbuf[bpos++] = c; if (bpos >= BSIZE) flushbuf()
  2548. X
  2549. void
  2550. windgoto(r, c)
  2551. register int    r, c;
  2552. X{
  2553. X    r += 1;
  2554. X    c += 1;
  2555. X
  2556. X    /*
  2557. X     * Check for overflow once, to save time.
  2558. X     */
  2559. X    if (bpos + 8 >= BSIZE)
  2560. X        flushbuf();
  2561. X
  2562. X    outbuf[bpos++] = '\033';
  2563. X    outbuf[bpos++] = '[';
  2564. X    if (r >= 10)
  2565. X        outbuf[bpos++] = r/10 + '0';
  2566. X    outbuf[bpos++] = r%10 + '0';
  2567. X    outbuf[bpos++] = ';';
  2568. X    if (c >= 10)
  2569. X        outbuf[bpos++] = c/10 + '0';
  2570. X    outbuf[bpos++] = c%10 + '0';
  2571. X    outbuf[bpos++] = 'H';
  2572. X}
  2573. X
  2574. XFILE *
  2575. fopenb(fname, mode)
  2576. char    *fname;
  2577. char    *mode;
  2578. X{
  2579. X    return fopen(fname, mode);
  2580. X}
  2581. END_OF_FILE
  2582. if test 2241 -ne `wc -c <'unix.c'`; then
  2583.     echo shar: \"'unix.c'\" unpacked with wrong size!
  2584. fi
  2585. # end of 'unix.c'
  2586. fi
  2587. echo shar: End of archive 1 \(of 4\).
  2588. cp /dev/null ark1isdone
  2589. MISSING=""
  2590. for I in 1 2 3 4 ; do
  2591.     if test ! -f ark${I}isdone ; then
  2592.     MISSING="${MISSING} ${I}"
  2593.     fi
  2594. done
  2595. if test "${MISSING}" = "" ; then
  2596.     echo You have unpacked all 4 archives.
  2597.     rm -f ark[1-9]isdone
  2598. else
  2599.     echo You still need to unpack the following archives:
  2600.     echo "        " ${MISSING}
  2601. fi
  2602. ##  End of shell archive.
  2603. exit 0
  2604.